package org.bravof.generate;

import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.bravof.common.CaseUtils;
import org.bravof.common.Constants;
import org.bravof.common.FileTypeEnum;
import org.bravof.common.PropertyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Log4j2
@Component
@Setter
@NoArgsConstructor
public class POGenerator implements Runnable {
    @Autowired
    private PropertyUtil propertyUtil;

    @Autowired
    private CaseUtils caseUtils;

    private File file;

    /**
     * 用以生成代码的源数据
     */
    private List<Map<String, String>> resourceMapList;

    public POGenerator(List<Map<String, String>> resourceMapList) {
        this.resourceMapList = resourceMapList;
    }

    private void execute() throws IOException {
        StringBuffer buffer = new StringBuffer();
        //生成包名
        buffer.append(Constants.PACKAGE);
        buffer.append(Constants.SPACE);
        buffer.append(propertyUtil.getPackNamePrefix());
        buffer.append(Constants.DOT);
        buffer.append(propertyUtil.getClassName().toLowerCase());
        buffer.append(Constants.DOT);
        buffer.append(FileTypeEnum.PO.name().toLowerCase());
        buffer.append(Constants.SEMICOLON);

        //生成空行
        buffer.append(Constants.NEW_LINE);
        buffer.append(Constants.NEW_LINE);

        //生成需要导入的包
        List<String> importList = Arrays.asList(propertyUtil.getImportListStr().split(Constants.SEMICOLON));
        for(String each : importList) {
            buffer.append(Constants.IMPORT + Constants.SPACE);
            buffer.append(each + Constants.SEMICOLON);
            buffer.append(Constants.NEW_LINE);
        }

        //生成空行
        buffer.append(Constants.NEW_LINE);

        //生成类注解
        List<String> annotationList = Arrays.asList(propertyUtil.getAnnotationListStr().split(Constants.SEMICOLON));
        for(String each : annotationList) {
            buffer.append(each + Constants.NEW_LINE);
        }

        //生成类主体
        buffer.append(Constants.PUBLIC + Constants.SPACE + Constants.CLASS + Constants.SPACE);
        String realClassName = caseUtils.snakeToUpperCame(propertyUtil.getClassName().toLowerCase());
        buffer.append(realClassName + FileTypeEnum.PO.name().toUpperCase() + Constants.SPACE);

        //生成实现接口
        if(!StringUtils.isEmpty(propertyUtil.getImplementListStr())) {
            buffer.append(Constants.IMPLEMENTS + Constants.SPACE);
            //实现接口的字符串
            String listOfInterface = StringUtils.join(propertyUtil.getImplementListStr().split(Constants.SEMICOLON));
            buffer.append(listOfInterface + Constants.SPACE);
        }
        buffer.append(Constants.BRACKETS_BIG_L);

        //生成空行
        buffer.append(Constants.NEW_LINE);

        //开始生成类成员变量
        Iterator<Map<String, String>> iterator = resourceMapList.iterator();
        while(iterator.hasNext()) {
            Map<String, String> next = iterator.next();
            Iterator<Map.Entry<String, String>> nextIterator = next.entrySet().iterator();
            while(nextIterator.hasNext()) {
                Map.Entry<String, String> fieldAndTyle = nextIterator.next();
                buffer.append(Constants.PRIVATE + Constants.SPACE);
                buffer.append(fieldAndTyle.getValue() + Constants.SPACE + caseUtils.snakeToLowerCamel(fieldAndTyle.getKey()) + Constants.SEMICOLON);
                buffer.append(Constants.NEW_LINE);
            }

        }
        buffer.append(Constants.BRACKETS_BIG_R);

        //输出到文件
        File folder = new File(propertyUtil.getOutPutFilePath());

        FileWriter fileWriter = null;
        try {
            //判断是否存在输出目录，不存在则创建
            if(!folder.exists()) {
                folder.mkdirs();
            }
            file = new File(propertyUtil.getOutPutFilePath() + Constants.SLASH + realClassName + FileTypeEnum.PO.name().toUpperCase() + Constants.DOT + Constants.JAVA);
            if(!file.exists()) {
                file.createNewFile();
            }
            fileWriter = new FileWriter(file);
            fileWriter.write(buffer.toString());
        } catch(IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            if(fileWriter != null) {
                fileWriter.close();
            }
        }
    }

    @Override
    public void run() {
        try {
            long start = System.currentTimeMillis();
            execute();
            long end = System.currentTimeMillis();
            log.info("生成 {} 结束,耗时 {} ms, 文件位置 -> {}", FileTypeEnum.DTO.name(), end - start, file.getAbsolutePath());

        } catch(IOException e) {
            log.error(e.getMessage(), e);
        }
    }
}
